﻿using MQTTnet;
using MQTTnet.Server;
using MQTTnet.Protocol;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using MQTTnet.Client.Receiving;

namespace MQTT.Server
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        List<TopicItem> Topics = new List<TopicItem>();

        private IMqttServer server;

        /// <summary>
        /// 这里使用wpf开发逻辑代码使用事件驱动(winform),而不是使用数据驱动(wpf)
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();

            server = new MqttFactory().CreateMqttServer();

            // 基本事件
            // 服务启动触发
            server.StartedHandler = new MqttServerStartedHandlerDelegate(ServerStarted);
            // 服务停止触发
            server.StoppedHandler = new MqttServerStoppedHandlerDelegate(ServerStoped);

            // 客户端连接时触发
            server.ClientConnectedHandler = new MqttServerClientConnectedHandlerDelegate(ClientConnected);
            // 客户端断开事触发
            server.ClientDisconnectedHandler = new MqttServerClientDisconnectedHandlerDelegate(ClientDisconnected);

            // 订阅/取消订阅
            server.ClientSubscribedTopicHandler = new MqttServerClientSubscribedHandlerDelegate(
                new Action<MqttServerClientSubscribedTopicEventArgs>(Server_ClientSubscribedTopic));
            server.ClientUnsubscribedTopicHandler = new MqttServerClientUnsubscribedTopicHandlerDelegate(
                new Action<MqttServerClientUnsubscribedTopicEventArgs>(Server_ClientUnsubscribedTopic));

            // 消息接收
            server.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(
                new Action<MqttApplicationMessageReceivedEventArgs>(Server_ApplicationMessageReceived));

        }

        /// <summary>
        /// 启动服务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        [Obsolete]
        private async void btnStart_Click(object sender, RoutedEventArgs e)
        {
            if (server != null)
            {
                MqttServerOptionsBuilder optionBuilder = new MqttServerOptionsBuilder();
                // 绑定IP
                optionBuilder.WithDefaultEndpointBoundIPAddress(IPAddress.Parse(this.tbHostAddr.Text));
                // 绑定端口
                optionBuilder.WithDefaultEndpointPort(int.Parse(this.tbHostPort.Text));
                // 超时
                optionBuilder.WithDefaultCommunicationTimeout(TimeSpan.FromMilliseconds(5000));
                // 绑定用户名和密码
                optionBuilder.WithConnectionValidator(ConnectionValidate);

                IMqttServerOptions options = optionBuilder.Build();
                await server.StartAsync(options);
            }
        }

        [Obsolete]
        private void ConnectionValidate(MqttConnectionValidatorContext context)
        {
            string un = "", pwd = "";
            this.Dispatcher.Invoke(() =>
            {
                un = this.tbUsername.Text;
                pwd = this.tbPassword.Text;
            });

            if (context.Username == un && context.Password == pwd)
            {
                // 验证通过
                context.ReturnCode = MqttConnectReturnCode.ConnectionAccepted;
                return;
            }

            // 验证不通过
            context.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
        }


        private void ServerStarted(EventArgs e)
        {
            WriteLog(">>> 服务已启动");
        }

        private void ServerStoped(EventArgs e)
        {
            WriteLog(">>> 服务已停止");
        }

        private void ClientConnected(MqttServerClientConnectedEventArgs e)
        {
            // 记录到客户端列表
            this.Dispatcher.Invoke(() =>
            {
                lbClients.Items.Add(e.ClientId);
            });
            WriteLog(">>> 客户端" + e.ClientId + "连接");

        }

        private void ClientDisconnected(MqttServerClientDisconnectedEventArgs e)
        {
            // 记录到客户端列表
            this.Dispatcher.Invoke(() =>
            {
                lbClients.Items.Remove(e.ClientId);
            });
            WriteLog(">>> 客户端" + e.ClientId + "断开");
        }

        private void Server_ClientSubscribedTopic(MqttServerClientSubscribedTopicEventArgs e)
        {
            var topic = Topics.FirstOrDefault(t => t.Topic == e.TopicFilter.Topic);
            if (topic == null)
            {
                topic = new TopicItem { Topic = e.TopicFilter.Topic, Count = 0 };
                Topics.Add(topic);
            }

            if (!topic.Clients.Exists(c => c == e.ClientId))
            {
                topic.Clients.Add(e.ClientId);
                topic.Count++;
            }

            this.Dispatcher.Invoke(() =>
            {
                this.lvTopic.Items.Clear();
                foreach (var item in this.Topics)
                {
                    this.lvTopic.Items.Add($"{item.Topic}:{item.Count}");
                }
            });

            WriteLog(">>> 客户端" + e.ClientId + "订阅主题" + e.TopicFilter.Topic);

        }

        private void Server_ClientUnsubscribedTopic(MqttServerClientUnsubscribedTopicEventArgs e)
        {
            var topic = Topics.FirstOrDefault(t => t.Topic == e.TopicFilter);
            if (topic != null)
            {
                topic.Count--;
                topic.Clients.Remove(e.ClientId);
            }

            this.Dispatcher.Invoke(() =>
            {
                this.lvTopic.Items.Clear();
                foreach (var item in this.Topics)
                {
                    this.lvTopic.Items.Add($"{item.Topic}:{item.Count}");
                }
            });
            WriteLog(">>> 客户端" + e.ClientId + "退订主题" + e.TopicFilter);
        }

        private void Server_ApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs e)
        {
            WriteLog(">>> 收到消息" + e.ApplicationMessage.ConvertPayloadToString() + ",来自客户端"
                + e.ClientId + ",主题为" + e.ApplicationMessage.Topic);
        }

        /// <summary>
        /// 停止服务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void btnStop_Click(object sender, RoutedEventArgs e)
        {
            if (server != null)
            {
                await server.StopAsync();
            }
        }

        public void WriteLog(string message)
        {
            // 判断线程是否有权访问此控件
            if (!(txtRich.CheckAccess()))
            {
                this.Dispatcher.Invoke(() =>
                {
                    WriteLog(message);
                });
                return;
            }

            string strTime = "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "]";
            txtRich.AppendText(strTime + message + "\r");
        }

    }
}
